/*
 * Salida.cpp
 *
 *  Created on: 02/10/2012
 */

#include "Salida.h"

Salida::Salida(Estacionamiento* estacionamiento, int numeroSalida, vector<Pipe>* pipesSalidas):
	numeroSalida (numeroSalida),
	estacionamiento (estacionamiento),
	pipesSalidas (pipesSalidas){

	Log::getInstance()->loguear("Salida " + intToString(numeroSalida) + ": creada.");
}

Salida::~Salida() {
	// Cierro los pipes
	for (vector<Pipe>::iterator it = pipesSalidas->begin(); it != pipesSalidas->end(); it++){
		it->cerrar();
	}

	Log::getInstance()->loguear("Salida " + intToString(this->numeroSalida) + ": destruida.");
}

void Salida::inicializar(){
	for (vector<Pipe>::iterator it = this->pipesSalidas->begin(); it != this->pipesSalidas->end(); it++){
		it->setearModo(LECTURA);
	}

	this->bloquearSeniales();
}

/**
 * Metodo que define que las seniales SIGINT y SIGTERM se bloquean.
 * El objetivo es que la salida no salga del loop del pipe para
 * manejar estas seniales.
 * Las seniales SIGINT y SIGTERM las agarra el terminador para finalizar
 * la ejecucion correctamente.
 */
void Salida::bloquearSeniales(){
	sigset_t set;
	sigemptyset(&set);
	sigaddset(&set, SIGINT);
	sigaddset(&set, SIGTERM);
	sigprocmask(SIG_BLOCK, &set, NULL);
}

void Salida::sacarAutos(){
	Ticket ticket;
	while(this->pipesSalidas->at(this->numeroSalida - 1).leer(&ticket, sizeof(Ticket)) > 0){
		Log::getInstance()->imprimir("Salida " + intToString(this->numeroSalida) +
				": Se libera el lugar " + intToString(ticket.getLugarOcupado()) + ".");
		this->estacionamiento->liberarLugar(ticket);
	}
	Log::getInstance()->imprimir("Salida " + intToString(this->numeroSalida) + ": Se cierra la salida.");
}

